﻿namespace WCBG.ToolsForUnity.Tools
{
    using System;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using UnityEngine;

    public class FTools
    {
        public static void AutoSetUIProperty<T>(T view, GameObject go)
        {
            Type type = view.GetType();
            foreach (PropertyInfo info in type.GetProperties())
            {
                if ((info.PropertyType != typeof(GameObject)) && (info.Name.Substring(0, 1) == "_"))
                {
                    Component component = FindComponentInChild(go, info.PropertyType, info.Name.Remove(0, 1));
                    if (component == null)
                    {
                        Debug.LogError("auto find component error! objname:" + info.Name);
                    }
                    else
                    {
                        info.SetValue(view, component, null);
                    }
                }
            }
        }

        public static Texture2D ConvertSpriteToTexture2D(Sprite sprite)
        {
            if (sprite == null)
            {
                return null;
            }
            int num = (int) sprite.rect.width;
            int num2 = (int) sprite.rect.height;
            Texture2D textured = new Texture2D(num, num2);
            Color[] colorArray = sprite.texture.GetPixels((int) sprite.rect.x, (int) sprite.rect.x, num, num2);
            textured.SetPixels(colorArray);
            textured.Apply();
            return textured;
        }

        public static Texture2D CreateSquareTexture(Texture2D sourceTex)
        {
            bool flag = sourceTex.width > sourceTex.height;
            int num = flag ? sourceTex.width : sourceTex.height;
            int num2 = flag ? sourceTex.height : sourceTex.width;
            Texture2D textured = new Texture2D(num, num);
            int num3 = (num - num2) / 2;
            int num4 = flag ? 0 : ((num - num2) / 2);
            int num5 = flag ? ((num - num2) / 2) : 0;
            int num6 = flag ? num : (((num - num2) / 2) + num2);
            int num7 = flag ? (((num - num2) / 2) + num2) : num;
            for (int i = 0; i < num; i++)
            {
                for (int j = 0; j < num; j++)
                {
                    bool flag2 = false;
                    if ((i < num4) || (i > (num6 - 1)))
                    {
                        flag2 = true;
                    }
                    if ((j < num5) || (j > (num7 - 1)))
                    {
                        flag2 = true;
                    }
                    Color pixel = Color.clear;
                    if (!flag2)
                    {
                        pixel = sourceTex.GetPixel(i - num4, j - num5);
                    }
                    textured.SetPixel(i, j, pixel);
                }
            }
            textured.Apply();
            return textured;
        }

        public static Component FindComponentInChild(GameObject go, Type type, string elementName)
        {
            if (go != null)
            {
                Component[] componentsInChildren = go.GetComponentsInChildren(type, true);
                foreach (Component component2 in componentsInChildren)
                {
                    if (component2.gameObject.name == elementName)
                    {
                        return component2;
                    }
                }
            }
            return null;
        }

        public static bool GetIntersectPoint(Vector2 a, Vector2 b, Vector2 c, Vector2 d, out Vector2 result)
        {
            result = Vector2.zero;
            float num = ((b.y - a.y) * (d.x - c.x)) - ((a.x - b.x) * (c.y - d.y));
            if (num == 0f)
            {
                return false;
            }
            float num2 = (((((b.x - a.x) * (d.x - c.x)) * (c.y - a.y)) + (((b.y - a.y) * (d.x - c.x)) * a.x)) - (((d.y - c.y) * (b.x - a.x)) * c.x)) / num;
            float num3 = -(((((b.y - a.y) * (d.y - c.y)) * (c.x - a.x)) + (((b.x - a.x) * (d.y - c.y)) * a.y)) - (((d.x - c.x) * (b.y - a.y)) * c.y)) / num;
            if ((((((num2 - a.x) * (num2 - b.x)) <= 0f) && (((num3 - a.y) * (num3 - b.y)) <= 0f)) && (((num2 - c.x) * (num2 - d.x)) <= 0f)) && (((num3 - c.y) * (num3 - d.y)) <= 0f))
            {
                result = new Vector2(num2, num3);
            }
            return true;
        }

        public static float GetPathDistance(Vector3[] path)
        {
            float num = 0f;
            for (int i = 0; i < (path.Length - 1); i++)
            {
                num += Vector3.Distance(path[i], path[i + 1]);
            }
            return num;
        }

        public static bool GetRaycastHit(Ray ray, float maxDistance, out RaycastHit outHit)
        {
            return Physics.Raycast(ray, out outHit, maxDistance);
        }
            

        public static bool GetRaycastHit(Ray ray, float maxDistance, out RaycastHit outHit, int layerMask, bool bOperation = true)
        {
            if (bOperation)
            {
                if (Physics.Raycast(ray, out outHit, maxDistance, ((int) 1) << layerMask))
                {
                    return true;
                }
            }
            else if (Physics.Raycast(ray, out outHit, maxDistance, layerMask))
            {
                return true;
            }
            return false;
        }

        public static bool GetRaycastHitPoint(Camera camera, Vector3 screenPoint, float maxDistance, out Vector3 outPoint)
        {
            outPoint = Vector3.zero;
            if ((camera != null) && GetRaycastHit(camera.ScreenPointToRay(screenPoint), maxDistance, out RaycastHit hit))
            {
                outPoint = hit.point;
                return true;
            }
            return false;
        }

        public static bool GetRaycastHitPoint(Camera camera, Vector3 screenPoint, float maxDistance, out Vector3 outPoint, int layerMask, bool bOperation = true)
        {
            outPoint = Vector3.zero;
            if ((camera != null) && GetRaycastHit(camera.ScreenPointToRay(screenPoint), maxDistance, out RaycastHit hit, layerMask, bOperation))
            {
                outPoint = hit.point;
                return true;
            }
            return false;
        }

        public static Vector3 GetRaycastHitPointByMousePoint(float distance = 99999f)
        {
            GetRaycastHitPoint(Camera.main, Input.mousePosition, 99999f, out Vector3 vector);
            return vector;
        }

        public static Vector3 GetRaycastHitPointByMousePoint(int layerMask, float distance = 99999f, bool bOperation = true)
        {
            GetRaycastHitPoint(Camera.main, Input.mousePosition, distance, out Vector3 vector, layerMask, bOperation);
            return vector;
        }

        public static Transform GetRaycastHitTarget(Camera camera, Vector3 screenPoint, float maxDistance)
        {
            if ((camera != null) && GetRaycastHit(camera.ScreenPointToRay(screenPoint), maxDistance, out RaycastHit hit))
            {
                return hit.transform;
            }
            return null;
        }

        public static Transform GetRaycastHitTarget(Camera camera, Vector3 screenPoint, float maxDistance, int layerMask, bool bOperation = true)
        {
            if ((camera != null) && GetRaycastHit(camera.ScreenPointToRay(screenPoint), maxDistance, out RaycastHit hit, layerMask, bOperation))
            {
                return hit.transform;
            }
            return null;
        }

        public static Transform GetRaycastHitTargetByMousePoint(float distance = 99999f) => 
            GetRaycastHitTarget(Camera.main, Input.mousePosition, distance);

        public static Transform GetRaycastHitTargetByMousePoint(int layerMask, float distance = 99999f, bool bOperation = true) => 
            GetRaycastHitTarget(Camera.main, Input.mousePosition, distance, layerMask, bOperation);

        public static Vector3 RotateByDir(Vector3 p, Vector3 n, float angle)
        {
            float x = n.x;
            float y = n.y;
            float z = n.z;
            double num4 = Math.Sin((double) angle);
            double num5 = Math.Cos((double) angle);
            double num6 = 1.0 - num5;
            double num7 = ((p.x * (((x * x) * num6) + num5)) + (p.y * (((x * y) * num6) - (z * num4)))) + (p.z * (((x * z) * num6) + (y * num4)));
            double num8 = ((p.x * (((x * y) * num6) + (z * num4))) + (p.y * (((y * y) * num6) + num5))) + (p.z * (((y * z) * num6) - (x * num4)));
            double num9 = ((p.x * (((x * z) * num6) - (y * num4))) + (p.y * (((y * x) * num6) + (x * num4)))) + (p.z * (((z * z) * num6) + num5));
            p = new Vector3((float) num7, (float) num8, (float) num9);
            return p;
        }
    }
}

